import 'dart:collection';
import 'dart:math';

import 'package:flutter/material.dart';

class ListWheelExample extends StatefulWidget {
  const ListWheelExample({super.key});

  @override
  State<ListWheelExample> createState() => _ListWheelExampleState();
}

class _ListWheelExampleState extends State<ListWheelExample> {
  int value = 0;

  LinkedHashMap<int, FixedExtentScrollController> controllerMap =
      LinkedHashMap();

  bool isScrollFromController = false;

  @override
  void initState() {
    super.initState();
    for (var i = 4; i >= 0; i--) {
      FixedExtentScrollController controller = FixedExtentScrollController();
      controllerMap[i] = controller;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.runtimeType.toString()),
      ),
      body: Column(
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(20.0),
            child: Container(
              decoration: BoxDecoration(
                  border: Border.all(
                color: Colors.grey,
                width: 1,
              )),
              height: 130,
              child: Row(
                children: controllerMap.keys.map((key) {
                  return _buildItem(key, controllerMap[key]);
                }).toList(),
              ),
            ),
          ),
          Text("this value = $value"),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _randomValue,
        child: const Icon(Icons.refresh),
      ),
    );
  }

  Widget _buildItem(int bits, ScrollController? controller) {
    return Expanded(
      child: ListWheelScrollView.useDelegate(
        magnification: 1,
        onSelectedItemChanged: (i) {
          onChange(bits, i);
        },
        controller: controller,
        itemExtent: 40,
        physics: const FixedExtentScrollPhysics(),
        overAndUnderCenterOpacity: 0.3,
        childDelegate: ListWheelChildBuilderDelegate(
          childCount: 10,
          builder: (BuildContext context, int index) {
            return Center(
              child: Text(
                index.toString(),
                style: const TextStyle(fontSize: 30),
              ),
            );
          },
        ),
      ),
    );
  }

  void onChange(int bits, int i) {
    if (isScrollFromController) {
      return;
    }
    int total = 0;
    for (var k in controllerMap.keys) {
      final controller = controllerMap[k]!;
      final v = (int.tryParse("1${'0' * k}") ?? 0) * controller.selectedItem;
      total += v;
    }

    value = total;
    setState(() {});
  }

  Future<void> _randomValue() async {
    final value = Random().nextInt(99999);
    this.value = value;
    isScrollFromController = true;

    const duration = Duration(milliseconds: 200);

    print(value);

    controllerMap.forEach((k, v) {
      final base = int.tryParse("1${'0' * k}") ?? 0;
      final target = value ~/ base % 10;
      v.animateToItem(target, duration: duration, curve: Curves.linear);
    });

    await Future.delayed(duration * 1.1);

    isScrollFromController = false;
    setState(() {});
  }
}
